#pragma once
#include "mylog.hpp"
#include "common.hpp"
#include "mymutex.hpp"
#include "Addr.hpp"
using namespace my_log;
const int defaultfd = -1;
const int defaultbacklog = 16;
// 基类Socket
class Socket
{
public:
    virtual ~Socket() {}
    virtual void Sock() = 0;
    virtual void  Bind(uint16_t port) = 0;
    virtual void  Listen(int backlog) = 0;
    virtual std::shared_ptr<Socket>  Accept(Addr* clinet) = 0;
    virtual void  Close()=0;
    //收发报文
    virtual int  Send(std::string& message)=0;
    virtual int  Recv(std::string* message)=0;
    //客户端
    virtual bool  Connect(std::string& ip,uint16_t port)=0;
public:
    void BuildListenMethod(uint16_t port, int backlog = defaultbacklog)
    {
        Sock();
        Bind(port);
        Listen(backlog);
    }
    void BuildClientMethod()
    {
        Sock();
    }
private:
};
// 子类继承,显式实现方法
class TcpSocket : public Socket
{
public:
    TcpSocket(int sockfd = defaultfd)
        : _sockfd(sockfd)
    {
    }
    void Sock() override // override用于检验这个函数是否构成重写
    {
        _sockfd = socket(AF_INET, SOCK_STREAM, 0);
        if (_sockfd < 0)
        {
            // 创建异端失败
            LOG(LogLevel::FATAL) << "异端创建失败";
            exit(sockerr);
        }
        LOG(LogLevel::DEBUG) << "异端创建成功fd:" << _sockfd;
    }
    void Bind(uint16_t port) override
    {
        Addr client(port);
        // 绑定
        int n = bind(_sockfd, (struct sockaddr *)client.pSockaddr(), client.Socklen());
        if (n < 0)
        {
            // 创建异端失败
            LOG(LogLevel::FATAL) << "客户端绑定失败";
            exit(binderr);
        }
        LOG(LogLevel::DEBUG) << "客户端绑定成功";
    }
    void Listen(int backlog) override
    {
        int n = listen(_sockfd, backlog);
        if(n<0)
        {
            //创建异端失败
            LOG(LogLevel::FATAL)<<"监听状态设置定失败";
            exit(listenerr);
        }
        LOG(LogLevel::DEBUG)<<"监听状态设置成功";
    }
    std::shared_ptr<Socket> Accept(Addr* client)override
    {
        //让accept函数返回一个智能指针
        struct sockaddr_in peer;
        socklen_t len=sizeof(peer);
        int sockfd=accept(_sockfd,(struct sockaddr*)&peer,&len);
        if(sockfd<0)
        {
            // LOG(LogLevel::WARNING)<<"Accept失败";
            return nullptr;
        }
        //accept成功
        client->SetAddr(peer);
        return std::make_shared<TcpSocket>(sockfd);
    }
    int Send(std::string& message)override
    {
        return send(_sockfd,message.c_str(),message.size(),0);
    }
    int Recv(std::string* message)override
    {
        char buffer[4096];
        ssize_t n=recv(_sockfd,buffer,sizeof(buffer)-1,0);
        //std::cout<<"Recv n="<<n<<std::endl;
        if(n>0)
        {
            buffer[n] = '\0';
            //读取成功
            *message+=buffer;
        }
        return n;
    }
    void Close()override
    {
        if(_sockfd>0)
        {
            close(_sockfd);
        }
    }
    bool Connect(std::string& ip,uint16_t port)override
    {
        Addr cli(ip,port);
        int n=connect(_sockfd,(struct sockaddr*)cli.pSockaddr(),cli.Socklen());
        if(n<0)
        {
            LOG(LogLevel::FATAL)<<"客户端连接失败";
            return false;
        }
        return true;
    }
    ~TcpSocket()
    {
    }

private:
    int _sockfd; // 可以为listensockfd,也可以为acceptsockfd
};